package com.dalonedrow.module.hq.ui.views;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.dalonedrow.engine.sprite.base.SimplePoint;
import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.engine.systems.base.Interactive;
import com.dalonedrow.engine.systems.base.ProjectConstants;
import com.dalonedrow.engine.ui.base.GuiComponent;
import com.dalonedrow.engine.ui.base.View;
import com.dalonedrow.engine.ui.base.border.BorderFactory;
import com.dalonedrow.engine.ui.base.menu.MenuGroup;
import com.dalonedrow.engine.ui.base.panel.LandscapePagePanel;
import com.dalonedrow.engine.ui.base.panel.PagePanel;
import com.dalonedrow.engine.ui.base.panel.Panel;
import com.dalonedrow.engine.ui.base.panel.PortraitPagePanel;
import com.dalonedrow.engine.ui.base.panel.SimpleScrollingTextPanel;
import com.dalonedrow.engine.ui.impl.Label;
import com.dalonedrow.engine.ui.impl.UIFactory;
import com.dalonedrow.globalvariables.constants.hq.GlobalConstants;
import com.dalonedrow.module.hq.DawnQuestGame;
import com.dalonedrow.module.hq.rpg.HQInteractiveObject;
import com.dalonedrow.module.hq.systems.HQMap;
import com.dalonedrow.module.hq.systems.HQScript;
import com.dalonedrow.module.hq.systems.MazeLoader;
import com.dalonedrow.module.hq.ui.widgets.HQActionMenu;
import com.dalonedrow.pooled.PooledStringBuilder;
import com.dalonedrow.pooled.StringBuilderPool;
import com.dalonedrow.utils.UtilityMethods;

/**
 * The title screen view.
 * @author Donald
 */
public final class DungeonScreenView implements View {
	/**
	 * the one and only instance of the <code>DungeonScreenView</code> class.
	 */
	private static DungeonScreenView	instance;
	/**
	 * Gives access to the singleton instance of {@link DungeonScreenView}.
	 * @return {@link DungeonScreenView}
	 */
	public static DungeonScreenView getInstance() {
		if (DungeonScreenView.instance == null) {
			DungeonScreenView.instance = new DungeonScreenView();
		}
		return DungeonScreenView.instance;
	}
	/** label for the current action. */
	private Label						currentAction;
	/** label for the IO whose turn it is. */
	private Label						currentIO;
	/** label for displaying how many moves are left. */
	private Label						currentMoves;
	/** label for the current turn number. */
	private Label						currentTurn;
	/** the title screen menu. */
	private MenuGroup					menu;
	/** the message panel. */
	private SimpleScrollingTextPanel	messagePanel;
	/** the panel used to organize menu items. */
	private PagePanel					panel;
	/** flag indicating initialization has been completed. */
	private boolean						runInit	= false;
	/**
	 * Creates the main panel.<br>
	 * |--------------------------------------|<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | MAP | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * | | |<br>
	 * |--------------------------------------|<br>
	 */
	private void createMainPanel() {
		panel = new LandscapePagePanel(Panel.LANDSCAPE_BOTTOM);
		Panel left = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		Panel right = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		Panel rtBtm = new PortraitPagePanel(Panel.PORTRAIT_LEFT);
		try {
		HQMap.getInstance().setBorder(
				BorderFactory.getInstance()
						.getBorderEdgeOf8ImagesBackgroundOf1Color(
								new int[] { 8, 8, 8, 8 },
								GlobalConstants.HQ_MONO_PANEL_BORDER,
								GlobalConstants.COL_HQ_MONO_PANEL_BACKGROUND,
								2,
								2));
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		left.addChild(HQMap.getInstance());
		final int eight = 8, c = 41;
		messagePanel = new SimpleScrollingTextPanel(
				ProjectConstants.getInstance().getFontH1(),
				eight, // 8 lines
				c, // 41 chars wide
				false // turn off debugging
		);
		left.addChild(messagePanel);

		currentTurn = UIFactory.getInstance().getStandardH1Label(
				"Turn 9999");
		currentIO = UIFactory.getInstance().getStandardH1Label(
				"xxxxxxxxxxxxxxxn");
		currentMoves = UIFactory.getInstance().getStandardH1Label(
				"Moves Left: 99");
		currentAction = UIFactory.getInstance().getStandardH1Label(
				"      gg  \n  ");
		currentAction.setHorizontalAlignment(GuiComponent.CENTER);
		currentAction.setHorizontalAlignment(GuiComponent.LEFT);
		rtBtm.addChild(HQActionMenu.getInstance());
		rtBtm.addChild(currentTurn);
		rtBtm.addChild(currentIO);
		rtBtm.addChild(currentMoves);
		rtBtm.addChild(currentAction);
		right.addChild(rtBtm);
		panel.addChild(left);
		panel.addChild(right);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMouseOver(final float x, final float y) {
		updateActionMessage("");
		if (ProjectConstants.getInstance().isPlayersTurn()) {
			panel.handleMouseOver(x, y);
		}
	}
	/**
	 * Initializes the {@link View}.
	 * @throws Exception if an error occurs
	 */
	public void init() throws Exception {
		if (!runInit) {
			createMainPanel();
			runInit = true;
		}
		// INIT IS RUN EVERY TIME THE SCREEN IS LOADED
		// get current map id from global script
		int currentMap =
				HQScript.getInstance().getGlobalIntVariableValue("currentMap");
		// get current map name
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("map");
		sb.append(currentMap);
		String n =
				HQScript.getInstance().getGlobalStringVariableValue(
						sb.toString());
		sb.returnToPool();
		HQMap.getInstance().loadMap(n);
		MazeLoader.getInstance().loadMaze(currentMap);
		SimplePoint pt = UtilityMethods.getInstance().centerComponentInFrame(
				panel);
		panel.setPosition(pt.getX(), pt.getY(), 0.0f);
		panel.setVisible(true);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean keyTyped(final char character) {
		switch (character) {
		case Keys.ESCAPE:
			System.out.println("esc");
			DawnQuestGame.getInstance().end();
			break;
		case Keys.UP:
			menu.highlightPrevious();
			break;
		case Keys.DOWN:
			menu.highlightNext();
			break;
		case Keys.ENTER:
			if (menu != null
					&& menu.isVisible()
					&& menu.getHighlighted() != null) {
				menu.getHighlighted().onSelect();
			}
			break;
		case Keys.TAB:
			if (menu != null) {
				if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)
						|| Gdx.input.isKeyPressed(Keys.SHIFT_RIGHT)) {
					menu.highlightPrevious();
				} else {
					menu.highlightNext();
				}
			}
			break;
		case Keys.BACKSPACE:
			try {} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
			break;
		case Keys.SPACE:
			try {
				// textfield.addCharacter(e.getKeyChar());
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
			break;
		default:
			if (Character.isLetterOrDigit(character)) {
				try {
					// textfield.addCharacter(e.getKeyChar());
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
			break;
		}
		return true;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		if (!runInit) {
			try {
				init();
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
		}
		updateTurn();
		panel.prepareForRendering();
	}
	/**
	 * Sends the player a message through the message panel.
	 * @param text the message
	 * @throws Exception if an error occurs
	 */
	public void sendPlayerMessage(final String text) throws Exception {
		messagePanel.updateText(text);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean touchUp(final int x, final int y, final int pointer,
			final int button) {
		updateActionMessage("");
		if (ProjectConstants.getInstance().isPlayersTurn()) {
			panel.touchUp(x, y, pointer, button);
		}
		return true;
	}
	/**
	 * Updates the current action message.
	 * @param msg the message
	 */
	public void updateActionMessage(final String msg) {
		currentAction.setText(msg);
	}
	/** Updates the turn label. */
	private void updateTurn() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		try {
			int turn = HQScript.getInstance().getGlobalIntVariableValue(
					"currentTurn");
			sb.append("Turn ");
			sb.append(turn);
			currentTurn.setText(sb.toString());
			sb.setLength(0);

			int ioid = HQScript.getInstance().getGlobalIntVariableValue(
					"ioTurn");
			if (ioid == -GlobalConstants.INT_999) {
				// zargon's turn
			} else {
				if (Interactive.getInstance().hasIO(ioid)) {
					HQInteractiveObject io =
							(HQInteractiveObject) Interactive.getInstance()
									.getIO(ioid);
					int prof = io.getPCData().getProfession();
					sb.append(GlobalConstants.CLASS_TITLES[prof]);
					if (GlobalConstants.CLASS_TITLES[prof].endsWith("s")
							|| GlobalConstants.CLASS_TITLES[prof].endsWith("x")
							|| GlobalConstants.CLASS_TITLES[prof].endsWith("z")) {
						sb.append("' Play");
					} else {
						sb.append("'s Play");
					}
					currentIO.setText(sb.toString());
					sb.setLength(0);
					// moves
					sb.append("Moves Left: ");
					int ml = io.getScript().getLocalVariable(
							"movesLeft").getIntVal();
					sb.append(ml);
					currentMoves.setText(sb.toString());
					sb.setLength(0);
				} else {
					// throw error;
				}
			}
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		} finally {
			sb.returnToPool();
		}
	}
}
